package com.ichifinga.airwave.shared.views;

import com.ichifinga.airwave.shared.DisplayThread;
import com.ichifinga.airwave.shared.entities.Phrase;
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;

public class DisplaySurfaceView extends SurfaceView implements Callback
{
	DisplayThread _thread;
	public boolean _editMode = false;
	public boolean _helpMode = false;
	Phrase _phrase;
		
	GestureDetector gd;
	
	public DisplaySurfaceView(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		this.setClickable(true);
		
		getHolder().addCallback(this);
		setClickable(true);
		
		gd = new GestureDetector(context, new gl());
		
		gd.setOnDoubleTapListener(new odl());
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event)
	{
		return gd.onTouchEvent(event);
	}

	private class gl implements OnGestureListener
	{
		@Override
		public boolean onDown(MotionEvent e)
		{
			return true;
		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,	float velocityY)
		{
			if(Math.abs((double)(e2.getRawX() - e1.getRawX())) > Math.abs((float)(e2.getRawY() - e1.getRawY())))
			{	
				if(e2.getRawX() > e1.getRawX())
				{
					_thread.SetPreviousFrame();
				}
				else
				{
					_thread.SetNextFrame();
				}
			}
			else if(!_editMode)
			{	
				if(e2.getRawY() > e1.getRawY())
				{
					KillThread();
					_phrase = Phrase.GetNextPhrase(getContext());
					StartThread(getWidth(), getHeight());
				}
				else
				{
					KillThread();
					_phrase = Phrase.GetPreviousPhrase(getContext());
					StartThread(getWidth(), getHeight());
				}
			}
			return true;
		}

		@Override
		public void onLongPress(MotionEvent e)
		{
			if(!_editMode)
			{
				KillThread();
				_phrase = Phrase.GetFirstPhrase(getContext());
				StartThread(getWidth(), getHeight());
			}
		}

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2,
				float distanceX, float distanceY)
		{
			return true;
		}

		@Override
		public void onShowPress(MotionEvent e)
		{
			
		}

		@Override
		public boolean onSingleTapUp(MotionEvent e)
		{
			return true;
		}
	}
	
	private class odl implements OnDoubleTapListener
	{
		@Override
		public boolean onDoubleTap(MotionEvent e)
		{
			return true;
		}

		@Override
		public boolean onDoubleTapEvent(MotionEvent e)
		{
			if(e.getAction() == MotionEvent.ACTION_UP)
			{
				_thread.SetFirstFrame();
			}
			return true;
		}

		@Override
		public boolean onSingleTapConfirmed(MotionEvent e)
		{
			return true;
		}
	}

	public void SetEditMode()
	{
		_editMode = true;
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 
	{
    	KillThread();
    	
    	StartThread(width, height);	
	}

	public void RefreshPhrase(Phrase phrase)
	{
		KillThread();
    	_phrase = phrase;
    	StartThread(getWidth(), getHeight());	
	}
	
	@Override
	public void surfaceCreated(SurfaceHolder holder)
	{
		_phrase = 
			_editMode
			? Phrase.GetEditPhrase(getContext())
			: Phrase.GetCurrentPhrase(getContext());
	}
	
	@Override
	public void surfaceDestroyed(SurfaceHolder holder)
	{
		KillThread();
	}
	
	private void KillThread()
	{
		if(_thread == null) return;
		
		boolean retry = true;
        _thread.setRunning(false);
        while (retry) {
            try {
                _thread.join();
                retry = false;
            } catch (InterruptedException e) {
                
            }
        }
	}
		
	private void StartThread(int width, int height)
	{
		_thread = new DisplayThread(getHolder(), _editMode, width, height, _phrase); 
  		
		_thread.setRunning(true);
		_thread.start();
	}
}
